package com.ruoyi.feike.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.activiti.service.impl.ActTaskServiceImpl;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.feike.domain.*;
import com.ruoyi.feike.mapper.AnnualReviewyMapper;
import com.ruoyi.feike.mapper.NotesMapper;
import com.ruoyi.feike.service.*;
import lombok.extern.slf4j.Slf4j;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author lss
 * @version 1.0
 * @description: 新增降低保证金比例申请审批流程接口
 * @date 2022/8/2 16:13
 */
@Service
@Slf4j
public class DepositDecreaseServiceImpl implements IDepositDecreaseService {

    private static final String INSTEANCEID = "depositDecrease";

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ProcessRuntime processRuntime;

    @Autowired
    private IBasicInformationService basicInformationService;

    @Autowired
    private IDealerNegativeInformationCheckService dealerNegativeInformationCheckService;

    @Autowired
    private ILimitCalculationForCommericalNeedsService limitCalculationForCommericalNeedsService;

    @Autowired
    private IOtherFinancingResourceService otherFinancingResourceService;

    @Autowired
    private ITemporaryConditionFollowUpService temporaryConditionFollowUpService;

    @Autowired
    private ISecuritiesService securitiesService;

    @Autowired
    private InstanceIdUtil instanceIdUtil;

    @Autowired
    private AnnualReviewyMapper annualReviewyMapper;

    @Autowired
    private NotesMapper notesMapper;

    @Autowired
    private ActTaskServiceImpl actTaskService;

    @Autowired
    private RuntimeService runtimeService;

    /**
     * @param newApplicationDTO
     * @description: 新经销商申请审批流程接口
     * @param: newApplicationDTO
     * @return: AjaxResult
     * @author lss
     * @date: 2022/8/2 15:15
     */
    @Override
    public AjaxResult insertActApprove(NewApplicationDTO newApplicationDTO) {

        String processDefinitionKey = newApplicationDTO.getProcessDefinitionKey();
        //生成流程task
        //String instanceId = IdUtils.get16UUID();
        String abbreviation = instanceIdUtil.getAbbreviationToMap(newApplicationDTO.getInstanceId());
        String currentVal = instanceIdUtil.getRedisInstanceId(abbreviation);


        String  instanceId = instanceIdUtil.getIstanceId(abbreviation, currentVal);
        Notes notes = new Notes();
        notes.setComments(newApplicationDTO.getComments());
        notes.setId(IdUtils.simpleUUID());
        notes.setInstanceId(instanceId);
        notesMapper.insertNotes(notes);

        Deployment deployment = repositoryService.createDeployment().key(newApplicationDTO.getInstanceId()).deploy();
//        String title = SecurityUtils.getLoginUser().getUser().getNickName()+"-"+deployment.getName();
        String title = newApplicationDTO.getInstanceName();
        Authentication.setAuthenticatedUserId(String.valueOf(SecurityUtils.getLoginUser().getUser().getUserId()));
        ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey(newApplicationDTO.getInstanceId()).withName(title).withBusinessKey(instanceId).build());
        //查询任务信息
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();


        TaskQuery query = taskService.createTaskQuery().taskCandidateOrAssigned(SecurityUtils.getUsername()).active();
        List<Task> todoList = query.list();//获取申请人的待办任务列表
        for (Task tmp : todoList) {
            if (tmp.getProcessInstanceId().equals(processInstance.getId())) {
                task = tmp;//获取当前流程实例，当前申请人的待办任务
                break;
            }
        }
        Map<String,Object> map=new HashMap<>();
        HashMap<String, Object> variables = new HashMap<String, Object>();
        for (ActFormDTO form : newApplicationDTO.getActForm()) {
            variables.put(String.valueOf(form.getControlId()), form.getControlValue());
        }
        variables.put("toUnderwriter", 0);
        taskService.complete(task.getId(), variables);

        //发送邮件
        try {
            org.activiti.engine.runtime.ProcessInstance processInstanceMe = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .singleResult();
            // 上一个节点的执行完，再次查询，获取下一个节点的任务信息
            org.activiti.engine.task.Task finalTask = taskService.createTaskQuery()
                    .processInstanceId(processInstanceMe.getProcessInstanceId())
                    .singleResult();
            ThreadUtil.execute(new Runnable() {

                @Override
                public void run() {
                    actTaskService.sendMail(finalTask, instanceId,null);
                }
            });
        } catch (Exception e) {
            log.error("邮件发送失败，{}",e.getMessage());
        }

        //插入基本信息
        int basicInfoFlag=1;
        if (StringUtils.isNotEmpty(newApplicationDTO.getDealername())){
            String sectorStr=null;
            for (BasicInformationDTO basicInformation:newApplicationDTO.getDealername()){
                basicInformation.setId(IdUtils.simpleUUID());
                if (StringUtils.isNotEmpty(basicInformation.getSector())){
                    for (String sector:basicInformation.getSector()){
                        sectorStr+=sector+",";
                    }
                    sectorStr.substring(0,sectorStr.length()-1);
                    basicInformation.setSectorStr(sectorStr);
                }
                basicInfoFlag=basicInformationService.insertBasicInformationByDto(basicInformation);
            }
        }
        //经销商信息
        int dealerInfoFlag=1;
        if (basicInfoFlag==1&& StringUtils.isNotEmpty(newApplicationDTO.getDealerInformationList())){
            for (DealerNegativeInformationCheck dealerNegativeInformationCheck:newApplicationDTO.getDealerInformationList()){
                dealerNegativeInformationCheck.setId(IdUtils.simpleUUID());
                dealerInfoFlag=dealerNegativeInformationCheckService.insertDealerNegativeInformationCheck(dealerNegativeInformationCheck);
            }
        }
        //销售业绩及目标
        int salstargetFlag=1;
        if (dealerInfoFlag==1&&StringUtils.isNotEmpty(newApplicationDTO.getLimit_calculation_for_commerical_needs())){
            for (LimitCalculationForCommericalNeeds limitCalculationForCommericalNeedsm:newApplicationDTO.getLimit_calculation_for_commerical_needs()){
                limitCalculationForCommericalNeedsm.setId(IdUtils.simpleUUID());
                salstargetFlag=limitCalculationForCommericalNeedsService.insertLimitCalculationForCommericalNeeds(limitCalculationForCommericalNeedsm);
            }
        }
        //经销商其他相关贷款信息
        int otherFinancFlag=1;
        if (salstargetFlag==1&&StringUtils.isNotEmpty(newApplicationDTO.getOther_financing_resource())){
            for (OtherFinancingResource otherFinancingResource:newApplicationDTO.getOther_financing_resource()){
                otherFinancingResource.setId(IdUtils.simpleUUID());
                otherFinancFlag=otherFinancingResourceService.insertOtherFinancingResource(otherFinancingResource);
            }
        }
        //经销商创建相关信息
        int temporaryFlag=1;
        if (otherFinancFlag==1&&StringUtils.isNotEmpty(newApplicationDTO.getTemporaryConditionFollowUpList())){
            for (TemporaryConditionFollowUp temporaryConditionFollowUp:newApplicationDTO.getTemporaryConditionFollowUpList()){
                temporaryConditionFollowUp.setId(IdUtils.simpleUUID());
                temporaryFlag=temporaryConditionFollowUpService.insertTemporaryConditionFollowUp(temporaryConditionFollowUp);
            }
        }
        //担保信息
        int securityFlag=1;
        if (temporaryFlag==1&&StringUtils.isNotEmpty(newApplicationDTO.getTemporaryConditionFollowUpList())){
            for ( Securities securities:newApplicationDTO.getSecuritieList()){
                securities.setId(IdUtils.simpleUUID());
                securityFlag=securitiesService.insertSecurities(securities);
            }
        }
        AnnualReviewy annualReviewy = new AnnualReviewy();
        annualReviewy.setId(IdUtils.simpleUUID());
        annualReviewy.setTitle(title);
        annualReviewy.setCreateTime(DateUtils.getNowDate());
        annualReviewy.setInstanceId(instanceId);
        annualReviewy.setState("0");
        annualReviewy.setType(newApplicationDTO.getInstanceId());
        annualReviewy.setCreateName(SecurityUtils.getNickName());
        annualReviewy.setCreateBy(SecurityUtils.getUsername());
        annualReviewy.setCreateTime(DateUtils.getNowDate());
        if(ObjectUtil.isNotEmpty(task)){
            annualReviewy.setStartNode(task.getName());
        }
        annualReviewyMapper.insertAnnualReviewy(annualReviewy);
        return AjaxResult.success("添加新经销商申请成功!");
    }

    @Override
    @DataSource(value = DataSourceType.SLAVE)
    public AjaxResult getForignList(DepositDecreaseDTO depositDecreaseDTO) {
        if(depositDecreaseDTO.getDealerName().length==0){
            depositDecreaseDTO.setDealerName(null);
        }
        List<String> titleList = new ArrayList<>();
        String[] yearMonthArr=this.getPreYearMonth();
        depositDecreaseDTO.setYearMonth(yearMonthArr);
        depositDecreaseDTO.setMinYearMonth(yearMonthArr[0]);
        depositDecreaseDTO.setMaxYearMonth(yearMonthArr[2]);
        String pivotStr="";
        String fieldStr="";
        List<Map<String,Object>> resultList=new ArrayList<>();
        if ("0".equals(depositDecreaseDTO.getIsDso())){
            pivotStr="pivot ( MAX(DSO) for PERIOD in (";
            for (int i=0;i<yearMonthArr.length;i++){
                pivotStr+=yearMonthArr[i]+",";
                fieldStr+= "DECODE(\""+yearMonthArr[i]+"\","+null+",0,"+"\""+yearMonthArr[i]+"\") AS \""+yearMonthArr[i]+"\",";
            }
            pivotStr=pivotStr.substring(0,pivotStr.length()-1);
            fieldStr=fieldStr.substring(0,fieldStr.length()-1);
            pivotStr+="))";
            depositDecreaseDTO.setPivotStr(pivotStr);
            depositDecreaseDTO.setFieldStr(fieldStr);
            resultList=annualReviewyMapper.getForeignDsoList(depositDecreaseDTO);
        }else{
            pivotStr="pivot ( MAX(AGING) for PERIOD in (";
            for (int i=0;i<yearMonthArr.length;i++){
                pivotStr+=yearMonthArr[i]+",";
                fieldStr+= "DECODE(\""+yearMonthArr[i]+"\","+null+",0,"+"\""+yearMonthArr[i]+"\") AS \""+yearMonthArr[i]+"\",";
            }
            pivotStr=pivotStr.substring(0,pivotStr.length()-1);
            fieldStr=fieldStr.substring(0,fieldStr.length()-1);
            pivotStr+="))";
            depositDecreaseDTO.setPivotStr(pivotStr);
            depositDecreaseDTO.setFieldStr(fieldStr);
            resultList=annualReviewyMapper.getForeignAingList(depositDecreaseDTO);
        }
        titleList.add("Dealer");
        titleList.add("Sector");
        for (String str:yearMonthArr){
            titleList.add(str);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("title", titleList);
        map.put("result", resultList);
        return AjaxResult.success(map);
    }

    @Override
    public Map<String, Object> getForeignInfo(LimitCalculationSearchDTO dto) {
        return null;
    }

    @Override
    @DataSource(value = DataSourceType.SLAVE)
    public List<Map<String,Object>> salesPerformanceAndTarget(SalesPerformanceAndTargetDTO dto) {
        List<Map<String,Object>> resultListOut=annualReviewyMapper.salesPerformanceAndTargetSellOut(dto);
        List<Map<String,Object>> resultListIn=annualReviewyMapper.salesPerformanceAndTargetSellIn(dto);
        resultListOut.addAll(resultListIn);
        return resultListOut;
    }

    @Override
    @DataSource(value = DataSourceType.SLAVE)
    public List<Map<String, Object>> wholesalePerformanceRecentMonthsOs(WholesalePerformanceRecentMonthsOsDTO dto) {
        List<Map<String,Object>> resultList=annualReviewyMapper.wholesalePerformanceRecentMonthsOs(dto);
        return resultList;
    }

    @Override
    @DataSource(value = DataSourceType.SLAVE)
    public List<Map<String, Object>> loyaltyPerformanceRecentQuarters(LoyaltyPerformanceRecentDTO dto) {
        return annualReviewyMapper.loyaltyPerformanceRecentQuarters(dto) ;
    }

    @Override
    @DataSource(value = DataSourceType.SLAVE)
    public List<LoyaltyPerformance6month> loyaltyPerformanceRecentMonths(LoyaltyPerformanceRecentDTO dto) {
        List<LoyaltyPerformance6month> loyaltyPerformance6months = annualReviewyMapper.loyaltyPerformanceRecentMonths(dto);
        for(LoyaltyPerformance6month lp6:loyaltyPerformance6months){
            if(null !=lp6.getValue()){
            lp6.setValue(Arith.getPercent(Double.parseDouble(lp6.getValue()),2));
            }
        }
        return loyaltyPerformance6months;
    }

    @Override
    @DataSource(value = DataSourceType.SLAVE)
    public List<LoyaltyPerformance6month> loyaltyPerformanceRecentMonthsRePenContract(LoyaltyPerformanceRecentDTO dto) {
        List<LoyaltyPerformance6month> loyaltyPerformance6months = annualReviewyMapper.loyaltyPerformanceRecentMonthsRePenContract(dto);
        for(LoyaltyPerformance6month lp6:loyaltyPerformance6months){
            if("RT Pen%".equals(lp6.getItem())){
                lp6.setValue(Arith.getPercent(Double.parseDouble(lp6.getValue()),2));
            }
        }
        return  loyaltyPerformance6months;
    }

    /**
     * @param depositDecreaseDTO
     * @description: 获取WHOLESALE PERFORMANCE-recent 3 months O/S外部数据源
     * @param:
     * @return:
     * @author
     * @date: 2022/8/18 17:44
     */
    @Override
    public List<Map<String, Object>> performanceRecentThreemonth(DepositDecreaseDTO depositDecreaseDTO) {

        return null;
    }

    /**
    * @description: 获取当前年月往前推两个月月份
    * @param:
    * @return:
    * @author lss
    * @date: 2022/8/11 10:42
    */
    private String[] getPreYearMonth(){
        String[] last12Months = new String[3];
        Calendar cal = Calendar.getInstance();
        // cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)+1); //要先+1,才能把本月的算进去
        cal.set(Calendar.DATE,1);
        for(int i=0; i<3; i++){
            cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)-1); //逐次往前推1个月
            if (cal.get(Calendar.MONTH)+1<10){
                last12Months[2-i] = cal.get(Calendar.YEAR)+ "0" + (cal.get(Calendar.MONTH)+1);
            }else {
                last12Months[2-i] = String.valueOf(cal.get(Calendar.YEAR))+ String.valueOf(cal.get(Calendar.MONTH)+1);
            }
        }
        return last12Months;
    }
}
